package cn.hgj.service;

import cn.hgj.entity.Order;
import cn.hgj.enums.OrderEvent;
import cn.hgj.enums.OrderStatus;
import cn.hgj.repository.OrderRepository;
import cn.hgj.util.IdGenerator;
import lombok.RequiredArgsConstructor;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.statemachine.StateMachine;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import reactor.core.publisher.Mono;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

//@Service
@RequiredArgsConstructor
public class OrderService {

    private final StateMachine<OrderStatus, OrderEvent> stateMachine;
    private final OrderRepository orderRepository;
    private final RabbitTemplate rabbitTemplate;



    /**
     * 状态机转换（带上下文）
     */
    @Transactional
    public void transitionOrderStatus(Order order, OrderEvent event, Map<String, Object> context) {
//        stateMachine.getStateMachineAccessor()
//                .doWithAllRegions(access -> access.resetStateMachine());
        stateMachine.getExtendedState().getVariables().put("order", order);
        // 构建包含上下文的消息
        Message<OrderEvent> message = MessageBuilder
                .withPayload(event)
                .copyHeaders(context)
                .build();


        boolean accepted = stateMachine.sendEvent(event);
        if (accepted) {
            OrderStatus newStatus = stateMachine.getState().getId();

            // 更新订单状态
            int updated = orderRepository.updateOrderStatus(
                    order.getOrderId(),
                    order.getStatus(),
                    newStatus);
            System.out.println("状态:"+order.getStatus()+"->"+newStatus);
            if (updated == 0) {
                throw new RuntimeException("状态转换失败: 乐观锁冲突或状态已变更");
            }

            order.setStatus(newStatus);
        }

    }

    /**
     * 支付回调处理（带支付信息）
     */
    @Transactional
    public void handlePaymentCallback(String orderId, boolean paymentSuccess,
                                      String paymentId, LocalDateTime paymentTime) {

        // 使用悲观锁查询（根据数据库类型可能需要调整）
        Order order = orderRepository.findById(orderId)
                .orElseThrow(() -> new RuntimeException("订单不存在: " + orderId));

        if (paymentSuccess) {
            // 构建支付上下文
            Map<String, Object> context = new HashMap<>();
            context.put("paymentId", paymentId);
            context.put("paymentTime", paymentTime);

            // 状态转换
            transitionOrderStatus(order, OrderEvent.PAY_SUCCESS, context);

            // 更新支付信息
            orderRepository.updateOrderWithPayment(
                    orderId,
                    OrderStatus.PAY_PENDING,
                    OrderStatus.PAY_SUCCESS,
                    paymentId,
                    paymentTime);

            // 发送异步处理消息（RabbitMQ）
            rabbitTemplate.convertAndSend("order.process.queue", order);
        } else {
            // 支付失败处理
            transitionOrderStatus(order, OrderEvent.PAY_FAILED, null);
        }
    }

    /**
     * 创建订单
     */
    @Transactional
    public Order createOrder(String userId, String productId, int quantity, BigDecimal amount) {
        Order order = new Order();
        order.setOrderId(IdGenerator.generateOrderId()); // 订单ID生成器
        order.setUserId(userId);
        order.setProductId(productId);
        order.setQuantity(quantity);
        order.setAmount(amount);
        order.setStatus(OrderStatus.INITIALIZED);

        // 保存订单
        order = orderRepository.save(order);

        // 状态转换：INITIALIZED -> PAY_PENDING
        transitionOrderStatus(order, OrderEvent.CREATE_ORDER, null);

        return order;
    }

    /**
     * 取消订单
     */
    @Transactional
    public void cancelOrder(String orderId, String reason) {
        // 使用悲观锁查询
        Order order = orderRepository.findById(orderId)
                .orElseThrow(() -> new RuntimeException("订单不存在: " + orderId));

        if (order.getStatus() == OrderStatus.PAY_PENDING) {
            // 构建取消上下文
            Map<String, Object> context = new HashMap<>();
            context.put("cancelReason", reason);

            // 状态转换
            transitionOrderStatus(order, OrderEvent.USER_CANCEL, context);

            rabbitTemplate.convertAndSend("order.process.queue","取消订单");
            // 库存回滚逻辑（此处省略）
            // inventoryService.rollbackStock(order.getProductId(), order.getQuantity());
        } else {
            throw new RuntimeException("订单当前状态不可取消");
        }
    }

    //@Scheduled(fixedRate = 60000) // 每分钟执行一次
    public void processTimeoutOrders() {
        LocalDateTime timeoutThreshold = LocalDateTime.now().minusMinutes(15);
        List<Order> pendingOrders = orderRepository.findByStatusAndCreateTimeBefore(
                OrderStatus.PAY_PENDING,
                timeoutThreshold
        );

        pendingOrders.forEach(order -> {
            try {
                //cancelOrder(order.getOrderId(), "支付超时自动取消");
                // 库存回滚操作
                //inventoryService.rollbackStock(order.getProductId(), order.getQuantity());
            } catch (Exception e) {
                System.out.println("处理超时订单失败: " + order.getOrderId());
            }
        });
    }
}
